<!DOCTYPE HTML>

<html>

<head>
    <meta name="viewport" content="width=device-width,user-scalable=no" />
    <!--    <script src="./tronweb.js"></script>-->
    <!--    <script src="./web3.min.js"></script>-->
    <script src="./abi.js"></script>
    <script src="./bignumber.js"></script>
</head>

<body>

</body>

<script>

    function callback(res) {
        OneMore.postMessage(JSON.stringify(res));
    }

    function callbackEthTransactionResult(res) {
        OneMore.ethTransactionResult(JSON.stringify(res));
    }

    async function ethSendTransaction(requestId, pk, transaction, rpc, waitForReceipt) {

        var result = { 'id': requestId, 'data': null, 'error': null };
        try {
            var tran = JSON.parse(transaction);
            let web3 = new Web3(rpc);
            let account = web3.eth.accounts.privateKeyToAccount(pk);

            if (!tran.nonce) {
                let count = await web3.eth.getTransactionCount(account.address, 'pending');
                tran.nonce = count;
            }

            let signature = await account.signTransaction(tran);
            web3.eth.sendSignedTransaction(signature.rawTransaction)
                    .on('transactionHash', function (hash) {
                        //这个事件代表交易已经被提交到以太坊网络，并且返回了交易的哈希值
                        result.data = hash;
                        if(!waitForReceipt) {
                            callback(result);
                        }
                    })
                    .on('receipt', function (receipt) {
                        if(waitForReceipt) {
                            callback(result);
                        }
                        result.data = receipt;
                        callbackEthTransactionResult(result);
                    })
                    .on('error', function (error) {
                        result.error = error.message;
                        callback(result);
                        callbackEthTransactionResult(result);
                    });

        } catch (e) {
            result.error = e.message;
            callback(result);
        }

    }

    async function ethEstimateGasFee(requestId, rpc, transaction) {
        var result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let tran = JSON.parse(transaction);
            let web3 = new Web3(rpc);
            let gasPrice = await web3.eth.getGasPrice();
            let gas = await web3.eth.estimateGas(tran);
            gas = parseInt(gas * 1.1);

            result.data = { 'gas': gas, 'gasPrice': gasPrice };

            callback(result);
        } catch (e) {
            result.error = e.message;
            callback(result);
        }

    }

    async function ethBuildSendTokenTransaction(requestId, type, rpc, from, to, token, tokenId, amount, gas, gasPrice) {

        var result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let web3 = new Web3(rpc);

            if (null == gasPrice || gasPrice.length == 0) {
                gasPrice = await web3.eth.getGasPrice();
            }

            var transaction;
            if (type == 'native') {
                //这里可以携带字符串信息，data => web3.utils.asciiToHex('Hello World')
                transaction = { from: from, to: to, value: web3.utils.toWei(amount, 'ether') };

                console.log(transaction);
                if (null == gas || gas.length == 0) {
                    gas = await web3.eth.estimateGas(transaction);
                    gas = parseInt(gas * 1.1);
                }
                transaction.gas = gas;
                transaction.gasPrice = gasPrice;
            } else {

                var transferMethods;

                if (type == 'token20') {
                    let contract = new web3.eth.Contract(abiErc20, token, { from: from });
                    let decimals = await contract.methods.decimals().call();
                    amount = new BigNumber(amount).multipliedBy(new BigNumber(10).pow(decimals)).toFixed(0);

                    transferMethods = contract.methods.transfer(to, amount);
                } else if (type == 'token721') {
                    let contract = new web3.eth.Contract(abiErc721, token, { from: from });
                    transferMethods = contract.methods.safeTransferFrom(from, to, new BigNumber(tokenId).toFixed(0));
                } else if (type == 'token1155') {
                    let contract = new web3.eth.Contract(abiErc1155, token, { from: from });
                    transferMethods = contract.methods.safeTransferFrom(from, to, new BigNumber(tokenId).toFixed(0), new BigNumber(amount).toFixed(0), []);
                } else {
                    result.error = 'no support';
                    callback(result);
                    return;
                }


                if (null == gas || gas.length == 0) {
                    gas = await transferMethods.estimateGas();
                    gas = parseInt(gas * 1.1);
                }
                console.log('gas:' + gas + ',gasPrice:' + gasPrice + ',amount:' + amount)

                transaction = { from: from, to: token, data: transferMethods.encodeABI(), gas: gas, gasPrice: gasPrice };
            }

            result.data = transaction;

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    async function checkOmpSwap(requestId, rpc, address, tokenA, tokenB, amountA, version) {
        var result = { 'id': requestId, 'data': null, 'error': null };
        try {

            let tokenPriceContract = '0xb6e401827DFC78262bc47EF6C04C37a534b9316f';
            let routerV2Contract = 1 == version ? '0xCACd778509Eb52E894172f69D0BB6EF8eeb32F48' : '0x1aaE9d3eb6d7e62b3c4Ef8eA3f0cD9AfBd5aa5e3';

            let web3 = new Web3(rpc);

            let contractA = new web3.eth.Contract(abiErc20, tokenA);
            let decimalsA = await contractA.methods.decimals().call();
            amountA = new BigNumber(amountA).multipliedBy(new BigNumber(10).pow(decimalsA)).toFixed(0);

            let balanceA = await contractA.methods.balanceOf(address).call();

            let contractB = new web3.eth.Contract(abiErc20, tokenB);
            let decimalsB = await contractB.methods.decimals().call();

            let balanceB = await contractB.methods.balanceOf(address).call();


            let contract = new web3.eth.Contract(abiTokenPrice, tokenPriceContract);
            let tokenPrice = await contract.methods.getTokenAmount2(routerV2Contract, tokenA, tokenB, amountA).call();

            console.log(tokenPrice);

            amountA = tokenPrice[0];
            let amountB = tokenPrice[1];

            let amountADecimals = new BigNumber(amountA).dividedBy(new BigNumber(10).pow(decimalsA)).toFixed(6);
            let balanceADecimals = new BigNumber(balanceA).dividedBy(new BigNumber(10).pow(decimalsA)).toFixed(6);

            let amountBDecimals = new BigNumber(amountB).dividedBy(new BigNumber(10).pow(decimalsB)).toFixed(6);
            let balanceBDecimals = new BigNumber(balanceB).dividedBy(new BigNumber(10).pow(decimalsB)).toFixed(6);

            let dataA = {
                'token': tokenA, 'address': address,
                'amount': amountA, 'amountDecimals': amountADecimals,
                'balance': balanceA, 'balanceDecimals': balanceADecimals
            };


            let dataB = {
                'token': tokenB, 'address': address,
                'amount': amountB, 'amountDecimals': amountBDecimals,
                'balance': balanceB, 'balanceDecimals': balanceBDecimals
            };

            result.data = [dataA, dataB];

            console.log(result);

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    async function buildOmpSwapTransaction(requestId, rpc, address, tokenA, tokenB, amountA, amountB, version) {
        var result = { 'id': requestId, 'data': null, 'error': null };
        try {

            let routerV2Contract = 1 == version ? '0xCACd778509Eb52E894172f69D0BB6EF8eeb32F48' : '0x1aaE9d3eb6d7e62b3c4Ef8eA3f0cD9AfBd5aa5e3';

            let web3 = new Web3(rpc);

            let gasPrice = await web3.eth.getGasPrice();

            let contractA = new web3.eth.Contract(abiErc20, tokenA, { from: address });
            let decimalsA = await contractA.methods.decimals().call();
            amountA = new BigNumber(amountA).multipliedBy(new BigNumber(10).pow(decimalsA)).toFixed(0);

            let allowedAmount = await contractA.methods.allowance(address, routerV2Contract).call();

            if (new BigNumber(amountA).comparedTo(new BigNumber(allowedAmount)) > 0) {
                console.log('需要授权');
                let approveMethods = contractA.methods.approve(routerV2Contract, new BigNumber(2).pow(256).minus(1).toFixed(0));
                let gas = await approveMethods.estimateGas();
                gas = parseInt(gas * 1.1);

                let transaction = { from: address, to: tokenA, data: approveMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

                console.log(transaction);
                result.data = transaction;
                callback(result);
                return;
            }

            let contractB = new web3.eth.Contract(abiErc20, tokenB);
            let decimalsB = await contractB.methods.decimals().call();
            amountB = new BigNumber(amountB).multipliedBy(new BigNumber(10).pow(decimalsB)).toFixed(0);

            let contract = new web3.eth.Contract(abiOmpSwapRouter, routerV2Contract, { from: address });

            let swapMethods = contract.methods.swapExactTokensForTokensSupportingFeeOnTransferTokens(
                amountA, amountB, [tokenA, tokenB], address, Date.now());

            let gas = await swapMethods.estimateGas();
            gas = parseInt(gas * 1.1);

            let transaction = { from: address, to: routerV2Contract, data: swapMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

            result.data = transaction;

            console.log(result);

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }


    async function ethBuildBatchSendNFTTransaction(requestId, type, rpc, batchContract, from, to, token, tokenIds, amounts, gas, gasPrice) {

        var result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let web3 = new Web3(rpc);

            if (null == gasPrice || gasPrice.length == 0) {
                gasPrice = await web3.eth.getGasPrice();
            }

            var transaction;

            var transferMethods;

            var targetContract;

            if (type == 'token721') {
                let contract = new web3.eth.Contract(abiErc721, token, { from: from });
                let isApproved = await contract.methods.isApprovedForAll(from, batchContract).call();
                console.log('是否授权:' + isApproved);
                if (isApproved) {
                    let transferContract = new web3.eth.Contract(aibMutileTransferNFT721, batchContract, { from: from });
                    transferMethods = transferContract.methods.multiTransfer(token, from, to, tokenIds.split(','));

                    targetContract = batchContract;
                } else {
                    console.log('需要授权');
                    let approveMethods = contract.methods.setApprovalForAll(batchContract, true);
                    let gas = await approveMethods.estimateGas();
                    gas = parseInt(gas * 1.1);

                    let transaction = { from: from, to: token, data: approveMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

                    console.log(transaction);
                    result.data = transaction;
                    callback(result);
                    return;
                }
            } else if (type == 'token1155') {
                let contract = new web3.eth.Contract(abiErc1155, token, { from: from });
                transferMethods = contract.methods.safeBatchTransferFrom(from, to, tokenIds.split(','), amounts.split(','), []);

                targetContract = token;
            } else {
                result.error = 'no support';
                callback(result);
                return;
            }


            if (null == gas || gas.length == 0) {
                gas = await transferMethods.estimateGas();
                gas = parseInt(gas * 1.1);
            }
            console.log('gas:' + gas + ',gasPrice:' + gasPrice + ',tokenIds:' + tokenIds)

            transaction = { from: from, to: targetContract, data: transferMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

            result.data = transaction;

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    async function buildAnySwapTransaction(requestId, rpc, token, anySwapContract, address, crossAddress, amount) {
        var result = { 'id': requestId, 'data': null, 'error': null };
        try {

            let web3 = new Web3(rpc);

            let gasPrice = await web3.eth.getGasPrice();

            let tokenContract = new web3.eth.Contract(abiErc20, token, { from: address });
            let decimals = await tokenContract.methods.decimals().call();
            amount = new BigNumber(amount).multipliedBy(new BigNumber(10).pow(decimals)).toFixed(0);

            let allowedAmount = await tokenContract.methods.allowance(address, anySwapContract).call();

            if (new BigNumber(amount).comparedTo(new BigNumber(allowedAmount)) > 0) {
                console.log('需要授权');
                let approveMethods = tokenContract.methods.approve(anySwapContract, new BigNumber(2).pow(256).minus(1).toFixed(0));
                let gas = await approveMethods.estimateGas();
                gas = parseInt(gas * 1.1);

                let transaction = { from: address, to: token, data: approveMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

                console.log(transaction);
                result.data = transaction;
                callback(result);
                return;
            }

            let crossContract = new web3.eth.Contract(abiAnySwap, anySwapContract, { from: address });

            let crossMethods = crossContract.methods.swapUsdt(crossAddress, amount);

            let gas = await crossMethods.estimateGas();
            gas = parseInt(gas * 1.1);

            let transaction = { from: address, to: anySwapContract, data: crossMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

            result.data = transaction;

            console.log(result);

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }


    async function ethbuildOMPBridgeTransaction(requestId, rpc, token, ompBridgeContract, address, crossAddress, amount) {
        var result = { 'id': requestId, 'data': null, 'error': null };
        try {

            let web3 = new Web3(rpc);

            let gasPrice = await web3.eth.getGasPrice();

            let tokenContract = new web3.eth.Contract(abiErc20, token, { from: address });
            let decimals = await tokenContract.methods.decimals().call();
            amount = new BigNumber(amount).multipliedBy(new BigNumber(10).pow(decimals)).toFixed(0);

            let allowedAmount = await tokenContract.methods.allowance(address, anySwapContract).call();

            if (new BigNumber(amount).comparedTo(new BigNumber(allowedAmount)) > 0) {
                console.log('需要授权');
                let approveMethods = tokenContract.methods.approve(anySwapContract, new BigNumber(2).pow(256).minus(1).toFixed(0));
                let gas = await approveMethods.estimateGas();
                gas = parseInt(gas * 1.1);

                let transaction = { from: address, to: token, data: approveMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

                console.log(transaction);
                result.data = transaction;
                callback(result);
                return;
            }

            let crossContract = new web3.eth.Contract(abiAnySwap, anySwapContract, { from: address });

            let crossMethods = crossContract.methods.swapUsdt(crossAddress, amount);

            let gas = await crossMethods.estimateGas();
            gas = parseInt(gas * 1.1);

            let transaction = { from: address, to: anySwapContract, data: crossMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

            result.data = transaction;

            console.log(result);

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }


    async function ethBuildOMPBridgeTransaction(requestId, rpc, ompBridgeContract, address, crossAddress, amount) {
        var result = { 'id': requestId, 'data': null, 'error': null };
        try {

            let fromToken = '0x437635BA437728c577f4234F3A3F48619f02d75c';
            let toToken = '0xA614F803B6FD780986A42C78EC9C7F77E6DED13C';
            let web3 = new Web3(rpc);

            let gasPrice = await web3.eth.getGasPrice();

            let tokenContract = new web3.eth.Contract(abiErc20, fromToken, { from: address });
            let decimals = await tokenContract.methods.decimals().call();
            amount = new BigNumber(amount).multipliedBy(new BigNumber(10).pow(decimals)).toFixed(0);

            let allowedAmount = await tokenContract.methods.allowance(address, ompBridgeContract).call();

            if (new BigNumber(amount).comparedTo(new BigNumber(allowedAmount)) > 0) {
                console.log('需要授权');
                let approveMethods = tokenContract.methods.approve(ompBridgeContract, new BigNumber(2).pow(256).minus(1).toFixed(0));
                let gas = await approveMethods.estimateGas();
                gas = parseInt(gas * 1.1);

                let transaction = { from: address, to: fromToken, data: approveMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

                console.log(transaction);
                result.data = transaction;
                callback(result);
                return;
            }

            let crossContract = new web3.eth.Contract(abiOmpBridge, ompBridgeContract, { from: address });

            let crossMethods = crossContract.methods.swap("728126428",
                [fromToken, toToken],
                [address, crossAddress],
                [amount, 0]);

            let gas = await crossMethods.estimateGas();
            gas = parseInt(gas * 1.1);

            let transaction = { from: address, to: ompBridgeContract, data: crossMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

            result.data = transaction;

            console.log(result);

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }


    async function checkAnySwapInfo(requestId, sellRpc, buyRpc, sellToken, buyToken, anySwapData, walletAddress) {
        var result = { 'id': requestId, 'data': null, 'error': null };
        try {

            let feeDesc;
            let minAmountDesc;
            let balanceSell;
            let balanceBuy;

            let sellWeb3 = new Web3(sellRpc);

            //check anyswap data
            let anySwapDataContract = new sellWeb3.eth.Contract(abiAnySwapData, anySwapData, { from: walletAddress });
            //check min amount
            let minAmount = await anySwapDataContract.methods.string2uintMapping('minAmount').call();
            minAmount = new BigNumber(minAmount).dividedBy(new BigNumber(10).pow(18)).toFixed(0);
            minAmountDesc = minAmount;

            //check fee type
            let feeType = await anySwapDataContract.methods.string2uintMapping('crossFeeType').call();

            //check fee
            let fee = await anySwapDataContract.methods.string2uintMapping('crossFee').call();
            if (feeType != 0) {
                feeDesc = new BigNumber(fee).dividedBy(new BigNumber(10).pow(18)).toFixed(0);
            }

            //check sell balance
            let tokenSellContract = new sellWeb3.eth.Contract(abiErc20, sellToken, { from: walletAddress });
            balanceSell = await tokenSellContract.methods.balanceOf(walletAddress).call();
            balanceSell = new BigNumber(balanceSell).dividedBy(new BigNumber(10).pow(18)).toFixed(5);


            //check buy balance
            let buyWeb3 = new Web3(buyRpc);
            let tokenBuyContract = new buyWeb3.eth.Contract(abiErc20, buyToken, { from: walletAddress });
            balanceBuy = await tokenBuyContract.methods.balanceOf(walletAddress).call();
            balanceBuy = new BigNumber(balanceBuy).dividedBy(new BigNumber(10).pow(18)).toFixed(5);

            result.data = { feeType: feeType, fee: feeDesc, minAmount: minAmountDesc, balanceSell: balanceSell, balanceBuy: balanceBuy };

            console.log(result);

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    function dateFormat(time,type = 'yyyy-MM-dd hh:mm'){
        let formatTime
        let date
        if(time === 0) {
            date = new Date()
        } else {
            if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
            time = parseInt(time)
            }
            if ((typeof time === 'number') && (time.toString().length === 10)) {
            time = time * 1000
            }
            date = new Date(time)
        }
        let Year = date.getFullYear()
        let month = date.getMonth() + 1
        let Month = month >= 10 ? month : '0' + month
        let day = date.getDate()
        let Day = day >= 10 ? day : '0' + day
        let Hour = date.getHours() < 10 ? '0' + (date.getHours()) : date.getHours()
        let Minute = date.getMinutes() < 10 ? '0' + (date.getMinutes()) : date.getMinutes()
        let Second = date.getSeconds() < 10 ? '0' + (date.getSeconds()) : date.getSeconds()
        if(type === 'yyyy-MM-dd'){
            formatTime = Year + '-' + Month + '-' + Day
            return formatTime
        } else if (type === 'yyyy-MM-dd hh:mm:ss'){
            formatTime = Year + '-' + Month + '-' + Day + ' ' + Hour + ':' + Minute + ':' + Second
            return formatTime
        } else if (type === 'yyyy-MM-dd hh:mm'){
            formatTime = Year + '/' + Month + '/' + Day + ' ' + Hour + ':' + Minute
            return formatTime
        } else if (type === 'MM-dd hh:mm'){
            formatTime = Month + '/' + Day + ' ' + Hour + ':' + Minute
            return formatTime
        } else if (type === 'hh:mm:ss'){
            formatTime = Hour + ':' + Minute + ':' + Second
            return formatTime
        } else {
            return "error type!"
        }
    }

    async function checkOmpMiningInfo(requestId, rpc, miningContractAddress, miningInviterContractAddress, userAddress) {
        let result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let data = {};
            let web3 = new Web3(rpc);
            //截取小数点后位数(web3FromWei)
            function getPointFive(res, num = 5) {
                let a = web3.utils.fromWei(res)
                let b = a.indexOf('.')
                if (b == -1) {
                    return a
                } else {
                    return a.slice(0, b + num + 1)
                }
            }
            let dex = new web3.eth.Contract(abiDexMining, miningContractAddress, { from: userAddress });
            let miningInfo = await dex.methods.getTotalMiningInfo(userAddress).call();
            data.total = getPointFive(miningInfo[0])
            data.person = getPointFive(miningInfo[1])
            data.excitation = getPointFive(miningInfo[2])
            data.grandTotal = getPointFive(miningInfo[3])
            data.waiting = getPointFive(miningInfo[4])
            data.second = getPointFive(miningInfo[5])
            data.waitUsdt = getPointFive(miningInfo[6])
            data.locking = getPointFive(miningInfo[7])
            let time = miningInfo[8];
            if(time == 0) {
                data.miningTime = '-'
            } else {
                data.miningTime = dateFormat(time)
            }

            let inviters = new web3.eth.Contract(abiInviters, miningInviterContractAddress, { from: userAddress });
            data.inviter = await inviters.methods.inviters(userAddress).call();

            result.data = data
            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    async function checkOmpPairMiningInfo(requestId, rpc, miningContractAddress, userAddress, pairId) {
        let result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let data = {};
            let web3 = new Web3(rpc);
            //截取小数点后位数(web3FromWei)
            function getPointFive(res, num = 5) {
                let a = web3.utils.fromWei(res)
                let b = a.indexOf('.')
                if (b == -1) {
                    return a
                } else {
                    return a.slice(0, b + num + 1)
                }
            }
            let dex = new web3.eth.Contract(abiDexMining, miningContractAddress, { from: userAddress });
            let miningInfo = await dex.methods.getMiningInfo(pairId,userAddress).call();
            data.total = getPointFive(miningInfo[0])
            data.person = getPointFive(miningInfo[1])
            data.excitation = getPointFive(miningInfo[2])
            data.grandTotal = getPointFive(miningInfo[3])
            data.waiting = getPointFive(miningInfo[4])
            data.second = getPointFive(miningInfo[5])
            data.waitUsdt = getPointFive(miningInfo[6])
            data.locking = getPointFive(miningInfo[7])

            result.data = data
            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    async function StartDexMining(requestId, rpc, miningContractAddress, userAddress){
        let result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let web3 = new Web3(rpc);
            let gasPrice = await web3.eth.getGasPrice();
            let mining = new web3.eth.Contract(abiDexMining, miningContractAddress, { from: userAddress });
            let res = await mining.methods.getAllWaitMiningIds(userAddress).call()
            let miningMethod = mining.methods.startMining(res)
            let gas = await miningMethod.estimateGas();
            gas = parseInt(gas * 1.1);
            let transaction = { from: userAddress, to: miningContractAddress, data: miningMethod.encodeABI(), gas: gas, gasPrice: gasPrice };
            result.data = transaction;
            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    async function miningClaimAll(requestId, rpc,miningContractAddress,inviteContractAddress,userAddress){
        let result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let web3 = new Web3(rpc);
            let inviters = new web3.eth.Contract(abiInviters, inviteContractAddress, { from: userAddress });
            let mining = new web3.eth.Contract(abiDexMining, miningContractAddress, { from: userAddress });
            const res = await inviters.methods.inviters(userAddress).call();
            if(res && res != '0x0000000000000000000000000000000000000000'){
                let gasPrice = await web3.eth.getGasPrice();
                let miningMethod = mining.methods.claimAll()
                let gas = await miningMethod.estimateGas();
                gas = parseInt(gas * 1.1);
                let transaction = { from: userAddress, to: miningContractAddress, data: miningMethod.encodeABI(), gas: gas, gasPrice: gasPrice };
                result.data = transaction;
                callback(result);
            } else {
                throw new Error('noInviter')
            }
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    async function bindSuperiorAddress(requestId, rpc,inviteContractAddress,userAddress,fatherAddress){
        let result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let web3 = new Web3(rpc);
            let gasPrice = await web3.eth.getGasPrice();
            let inviters = new web3.eth.Contract(abiInviters, inviteContractAddress, { from: userAddress });
            let invitersMethod = inviters.methods.setInviter(fatherAddress)
            let gas = await invitersMethod.estimateGas();
            gas = parseInt(gas * 1.1);
            let transaction = { from: userAddress, to: inviteContractAddress, data: invitersMethod.encodeABI(), gas: gas, gasPrice: gasPrice };
            result.data = transaction;
            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    async function checkOmpDexInfo(requestId, rpc, dexContractAddress, userAddress, pairId, priceDepthDecimals, maxLen) {
        var result = { 'id': requestId, 'data': null, 'error': null };
        try {

            let data = {};

            let web3 = new Web3(rpc);
            let dex = new web3.eth.Contract(abiDex, dexContractAddress, { from: userAddress });
            let pairInfo = await dex.methods.getPairInfo(pairId).call();

            data.price = pairInfo.price;
            data.priceDecimals = pairInfo.priceDecimals;
            data.token0 = pairInfo.token0;
            data.token0Decimals = pairInfo.token0Decimals;
            data.token1 = pairInfo.token1;
            data.token1Decimals = pairInfo.token1Decimals;

            data.tradeLimitMinRate = pairInfo.tradeLimitMinRate;
            data.tradeLimitMaxRate = pairInfo.tradeLimitMaxRate;
            data.tradeMarketBuyRate = '150';
            data.tradeMarketSellRate = '50';

            let token0Contract = new web3.eth.Contract(abiErc20, data.token0, { from: userAddress });
            data.token0Balance = await token0Contract.methods.balanceOf(userAddress).call();

            let token1Contract = new web3.eth.Contract(abiErc20, data.token1, { from: userAddress });
            data.token1Balance = await token1Contract.methods.balanceOf(userAddress).call();

            let depth = await dex.methods.getOrdersPriceAmount(pairId, priceDepthDecimals, maxLen).call();
            data.buyPrices = depth.buyPrices;
            data.buyAmounts = depth.buyAmounts;
            data.buyRemainAmounts = depth.buyRemainAmounts;
            data.sellPrices = depth.sellPrices;
            data.sellAmounts = depth.sellAmounts;
            data.sellRemainAmounts = depth.sellRemainAmounts;

            let orders = await dex.methods.getActiveOrders(userAddress, pairId).call();
            data.activeOrders = orders.map(function (value) {
                let order = {};
                order.id = value.id;
                order.pairId = value.pairId;
                order.price = value.price;
                order.amount = value.amount;
                order.remainAmount = value.remainAmount;
                order.createTime = value.createTime;
                order.dexType = value.dexType;
                order.tradeType = value.tradeType;
                order.user = value.user;
                return order;
            });

            result.data = data;

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }
    }

    async function buildDexTransaction(requestId, rpc, dexContractAddress, dexDelegateContractAddress, userAddress, pairId, price, amount, dexType, tradeType) {

        var result = { 'id': requestId, 'data': null, 'error': null };

        try {

            let web3 = new Web3(rpc);

            let gasPrice = await web3.eth.getGasPrice();

            let dex = new web3.eth.Contract(abiDex, dexContractAddress, { from: userAddress });
            let pairInfo = await dex.methods.getPairInfo(pairId).call();

            let tokenContract = new web3.eth.Contract(abiErc20, dexType == 0 ? pairInfo.token1 : pairInfo.token0, { from: userAddress });

            let token0Amount = new BigNumber(amount).multipliedBy(new BigNumber(10).pow(pairInfo.token0Decimals));
            let token1Amount = new BigNumber(amount).multipliedBy(pairInfo.price).dividedBy(new BigNumber(10).pow(pairInfo.priceDecimals))
                .multipliedBy(new BigNumber(10).pow(pairInfo.token1Decimals));
            let allowedAmount = await tokenContract.methods.allowance(userAddress, dexDelegateContractAddress).call();
            if ((dexType == 0 && token1Amount.comparedTo(allowedAmount) > 0) || (dexType == 1 && token0Amount.comparedTo(allowedAmount) > 0)) {
                let approveMethods = tokenContract.methods.approve(dexDelegateContractAddress, new BigNumber(2).pow(256).minus(1).toFixed(0));
                let gas = await approveMethods.estimateGas();
                gas = parseInt(gas * 1.1);

                let transaction = { from: userAddress, to: dexType == 0 ? pairInfo.token1 : pairInfo.token0, data: approveMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

                console.log(transaction);
                result.data = transaction;
                callback(result);
                return;
            }

            let tokenPrice = new BigNumber(price).multipliedBy(new BigNumber(10).pow(pairInfo.priceDecimals));

            let dexMethods = dex.methods.createDexOrder(pairId, tokenPrice.toFixed(0), token0Amount.toFixed(0), dexType, tradeType);

            let gas = await dexMethods.estimateGas();
            gas = parseInt(gas * 1.1);

            let transaction = { from: userAddress, to: dexContractAddress, data: dexMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

            result.data = transaction;

            callback(result);

        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }

    }

    async function buildDexCancelTransaction(requestId, rpc, dexContractAddress, userAddress, orderId) {

        var result = { 'id': requestId, 'data': null, 'error': null };

        try {

            let web3 = new Web3(rpc);

            let gasPrice = await web3.eth.getGasPrice();

            let dex = new web3.eth.Contract(abiDex, dexContractAddress, { from: userAddress });

            let dexMethods = dex.methods.cancelOrder(orderId);

            let gas = await dexMethods.estimateGas();
            gas = parseInt(gas * 1.1);

            let transaction = { from: userAddress, to: dexContractAddress, data: dexMethods.encodeABI(), gas: gas, gasPrice: gasPrice };

            result.data = transaction;

            callback(result);

        } catch (e) {
            console.log(e);
            result.error = e.message;
            callback(result);
        }

    }

    async function tronSign(requestId, pk, message, tronApiKey) {
        var result = { 'id': requestId, 'data': null, 'error': null };

        var isJson = false;
        try {
            isJson = JSON.parse(message);
        } catch (e) {

        }

        try {

            let tronWeb = new TronWeb({
                fullHost: 'https://api.trongrid.io',
                headers: { "TRON-PRO-API-KEY": tronApiKey },
                privateKey: pk
            });
            const signedMessage = await tronWeb.trx.sign(isJson ? JSON.parse(message) : message);
            result.data = isJson ? JSON.stringify(signedMessage) : signedMessage;
            callback(result);
        } catch (e) {
            result.error = e.message;
            callback(result);
        }
    }



    async function tronBuildSendTokenTransaction(requestId, type, from, to, token, tokenId, amount, tronApiKey) {

        var result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let tronWeb = new TronWeb({
                fullHost: 'https://api.trongrid.io',
                headers: { "TRON-PRO-API-KEY": tronApiKey },
                privateKey: ''
            });

            tronWeb.setAddress(from);

            let options = {
                callValue: 0
            };

            var transaction;
            if (type == 'native') {
                transaction = await tronWeb.transactionBuilder.sendTrx(to, tronWeb.toSun(amount), from, options);
                transaction.energy_used = 0;
            } else {

                var parameter;
                var functionStr;
                if (type == 'token20') {

                    let contract = await tronWeb.contract().at(token);
                    let decimals = await contract.decimals().call();

                    amount = new BigNumber(amount).multipliedBy(new BigNumber(10).pow(decimals)).toFixed(0);

                    functionStr = 'transfer(address,uint256)';
                    var parameter = [{ type: 'address', value: to }, { type: 'uint256', value: amount }];
                } else if (type == 'token721') {
                    functionStr = 'safeTransferFrom(address,address,uint256)';
                    var parameter = [{ type: 'address', value: from }, { type: 'address', value: to }, { type: 'uint256', value: tokenId }];
                } else if (type == 'token1155') {
                    functionStr = 'safeTransferFrom(address,address,uint256,uint256,bytes)';
                    var parameter = [{ type: 'address', value: from }, { type: 'address', value: to },
                    { type: 'uint256', value: tokenId }, { type: 'uint256', value: amount }, { type: 'bytes', value: '' }];
                } else {
                    result.error = 'no support';
                    callback(result);
                    return;
                }

                transaction = await tronWeb.transactionBuilder.triggerSmartContract(
                    token,
                    functionStr, options, parameter, tronWeb.defaultAddress.base58);

                transaction = transaction.transaction;

                let constantTransaction = await tronWeb.transactionBuilder.triggerConstantContract(
                    token,
                    functionStr, options, parameter, tronWeb.defaultAddress.base58);

                transaction.energy_used = constantTransaction.energy_used;

                let chainParameters = await tronWeb.trx.getChainParameters();
                for (var c in chainParameters) {
                    var data = chainParameters[c];
                    if (data.key == 'getEnergyFee') {
                        transaction.energy_used = (transaction.energy_used * data.value / 1000000).toFixed(4);
                        break;
                    }
                }
            }


            console.log(transaction);
            result.data = transaction;

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message ?? e.toString();
            callback(result);
        }
    }


    async function tronBuildOmpBridgeTransaction(requestId, rpc, ompBridgeContract, address, crossAddress, amount, tronApiKey) {

        var result = { 'id': requestId, 'data': null, 'error': null };
        try {
            let tronWeb = new TronWeb({
                fullHost: 'https://api.trongrid.io',
                headers: { "TRON-PRO-API-KEY": tronApiKey },
                privateKey: ''
            });

            tronWeb.setAddress(address);

            let options = {
                callValue: 0
            };

            let fromToken = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t';
            let toToken = 'TG7utH4CwmukDBoUZ9YQnqAay2NziuxJcH';

            amount = new BigNumber(amount).multipliedBy(new BigNumber(10).pow(6));
            let tokenContract = await tronWeb.contract().at(fromToken);
            let resultArray = await tokenContract.allowance(address, ompBridgeContract).call();
            let allowanceResult = JSON.parse(resultArray[0]);

            let allowanceAmount = new BigNumber(allowanceResult);

            console.log('allowance:' + allowanceAmount + ',amount:' + amount);

            if (amount.comparedTo(allowanceAmount) > 0) {
                console.log('需要授权');
                var functionStr = 'approve(address,uint256)';
                var parameter = [{ type: 'address', value: ompBridgeContract }, { type: 'uint256', value: new BigNumber(2).pow(256).minus(1).toFixed(0) }];

                transaction = await tronWeb.transactionBuilder.triggerSmartContract(
                    fromToken,
                    functionStr, options, parameter, tronWeb.defaultAddress.base58);

                transaction = transaction.transaction;

                let constantTransaction = await tronWeb.transactionBuilder.triggerConstantContract(
                    fromToken,
                    functionStr, options, parameter, tronWeb.defaultAddress.base58);

                transaction.energy_used = constantTransaction.energy_used;

                let chainParameters = await tronWeb.trx.getChainParameters();
                for (var c in chainParameters) {
                    var data = chainParameters[c];
                    if (data.key == 'getEnergyFee') {
                        transaction.energy_used = (transaction.energy_used * data.value / 1000000).toFixed(4);
                        break;
                    }
                }

                result.data = transaction;
                callback(result);
                return;
            }

            var functionStr = 'swap(uint256,address[],address[],uint256[])';
            var parameter = [{ type: 'uint256', value: 11552 },
            { type: 'address[]', value: [fromToken, toToken] },
            { type: 'address[]', value: [address, crossAddress] },
            { type: 'uint256[]', value: [amount.toFixed(0), 0] }];

            transaction = await tronWeb.transactionBuilder.triggerSmartContract(
                ompBridgeContract,
                functionStr, options, parameter, tronWeb.defaultAddress.base58);

            transaction = transaction.transaction;

            let constantTransaction = await tronWeb.transactionBuilder.triggerConstantContract(
                ompBridgeContract,
                functionStr, options, parameter, tronWeb.defaultAddress.base58);

            transaction.energy_used = constantTransaction.energy_used;

            let chainParameters = await tronWeb.trx.getChainParameters();
            for (var c in chainParameters) {
                var data = chainParameters[c];
                if (data.key == 'getEnergyFee') {
                    transaction.energy_used = (transaction.energy_used * data.value / 1000000).toFixed(4);
                    break;
                }
            }



            result.data = transaction;

            callback(result);
        } catch (e) {
            console.log(e);
            result.error = e.message ?? e.toString();
            callback(result);
        }
    }

    async function tronSendTransaction(requestId, pk, message, tronApiKey, waitForReceipt) {
        var result = { 'id': requestId, 'data': null, 'error': null };

        try {
            let tronWeb = new TronWeb({
                fullHost: 'https://api.trongrid.io',
                headers: { "TRON-PRO-API-KEY": tronApiKey },
                privateKey: pk
            });
            const signedTxn = await tronWeb.trx.sign(JSON.parse(message));
            const receipt = await tronWeb.trx.sendRawTransaction(signedTxn);
            result.data = receipt.txid;
            if (waitForReceipt) {

                var count = 0;
                var intervalID = setInterval(() => {
                    if (count >= 20) {
                        clearInterval(intervalID);
                        callback(result);
                        return;
                    }
                    count++;
                    tronWeb.trx.getTransactionInfo(result.data).then(transactionInfo => {
                        console.log('get tron transaction info:' + JSON.stringify(transactionInfo));
                        if (transactionInfo.receipt) {
                            clearInterval(intervalID);
                            if (transactionInfo.receipt.result === 'SUCCESS') {
                                callback(result);
                            } else {
                                result.error = 'error:execute revert track';
                                callback(result);
                            }
                        }

                    }).catch(err => {
                        clearInterval(intervalID);
                        result.error = 'error:execute revert';
                        callback(result);
                    });

                }, 5000);

            } else {
                callback(result);
            }
        } catch (e) {
            result.error = e.message;
            callback(result);
        }
    }


</script>

</html>